//
// Created by zzc on 17-12-26.
//

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include <ctype.h>
#include "../src/sds.h"
#include <string.h>





void test_newlen(void **state)
{
    sds s = sdsnewlen("hello", 5);
    assert_int_equal('h', s[0]);
    assert_int_equal(5, sdslen(s));
    sdsfree(s);
}

void test_empty(void **state)
{
    sds s = sdsempty();
    assert_int_equal(0, sdslen(s));
    assert_int_equal(0, sdsavail(s));
    sdsfree(s);
}

void test_new(void **state)
{
    sds s = sdsnew("hello");
    assert_int_equal(5, sdslen(s));
    assert_int_equal(0, sdsavail(s));
    sdsfree(s);
}

void test_dup(void **state)
{
    sds s = sdsnew("hello");
    sds s1 = sdsdup(s);
    assert_int_equal(5, sdslen(s1));
    assert_int_equal(0, sdsavail(s1));
    sdsfree(s);
    sdsfree(s1);
}

void test_growzero(void **state)
{
    sds s = sdsnew("hello");
    s = sdsgrowzero(s, 10);
    assert_int_equal(0, s[9]);
    assert_int_equal(10, sdslen(s));
    sdsfree(s);
}

void test_catlen(void **state)
{
    sds s = sdsnew("hello");
    s = sdscatlen(s, " world", 6);
    print_message("s free : %d", sdsavail(s));
    assert_int_equal(11, sdslen(s));
    assert_true(strcmp(s, "hello world") == 0);
    assert_int_equal(11, strlen(s));
}

void test_cat(void **state)
{
    sds s = sdsnew("hello");
    s = sdscat(s, " world");
    assert_int_equal(11, sdslen(s));
    print_message("s : %s", s);
    assert_true(strcmp(s, "hello world") == 0);
    assert_int_equal(11, strlen(s));
}

void test_catsds(void **state)
{
    sds s = sdsnew("hello");
    s = sdscat(s, sdsnew(" world"));
    assert_int_equal(11, sdslen(s));
    print_message("s : %s", s);
    assert_true(strcmp(s, "hello world") == 0);
    assert_int_equal(11, strlen(s));
}

void test_cpylen(void **state)
{
    sds s = sdsempty();
    s = sdscpylen(s, "hello", 5);

    assert_true(strcmp(s, "hello") == 0);
    assert_int_equal(5, strlen(s));
    assert_int_equal(5, sdslen(s));
    print_message("s:%s, len:%d, free:%d", s, sdslen(s), sdsavail(s));
    sdsfree(s);

    s = sdsnew("hello1");
    s = sdscpylen(s, "hello", 5);

    assert_true(strcmp(s, "hello") == 0);
    assert_int_equal(5, strlen(s));
    assert_int_equal(5, sdslen(s));
    print_message("s:%s, len:%d, free:%d", s, sdslen(s), sdsavail(s));
    sdsfree(s);
}

void test_trim(void **state)
{
    sds s = sdsnew("A... a. Hello World   ::A");
    s = sdstrim(s, "Aa.: ");
    print_message("s:%s, len:%d, free:%d", s, sdslen(s), sdsavail(s));
    assert_int_equal(11, sdslen(s));
    assert_true(strcmp(s, "Hello World") == 0);
    assert_int_equal(11, strlen(s));
    sdsfree(s);
}

void test_range(void **state)
{
    sds s = sdsnew("hello world");
    sdsrange(s, 0, -2);
    assert_int_equal(1, sdsavail(s));
    assert_true(strcmp(s, "hello worl") == 0);
    sdsrange(s, 0, 1);
    assert_int_equal(2, sdslen(s));
    assert_true(strcmp(s, "he") == 0);
    sdsfree(s);
    s = sdsnew("hello world");
    sdsrange(s, 1, 1);
    assert_int_equal(1, sdslen(s));
    assert_true(strcmp(s, "e") == 0);

    sdsrange(s, 2, 3);

    assert_int_equal(0, sdslen(s));
    sdsfree(s);
}

void test_cmp(void **state)
{
    sds s1 = sdsnew("zz");
    sds s2 = sdsnew("zz");
    assert_int_equal(0, sdscmp(s1, s2));
    sdsfree(s1); sdsfree(s2);

    s1 = sdsnew("zz");
    s2 = sdsnew("zzc");
    assert_true(0 > sdscmp(s1, s2));
    sdsfree(s1); sdsfree(s2);

    s1 = sdsnew("ab");
    s2 = sdsnew("ac");
    assert_true(0 > sdscmp(s1, s2));
    sdsfree(s1); sdsfree(s2);
}


void test_splitlen(void **state)
{
    int c;
    sds *token1 = sdssplitlen("a b c d e", 9, " ", 1, &c);
    assert_int_equal(5, c);
    assert_true(strcmp(token1[0], "a") == 0);
    assert_true(strcmp(token1[1], "b") == 0);
    assert_true(strcmp(token1[2], "c") == 0);
    assert_true(strcmp(token1[3], "d") == 0);
    assert_true(strcmp(token1[4], "e") == 0);
    sdsfreesplitres(token1, c);
}

void test_slowerupper(void **state)
{
    sds s = sdsnew("heLLo");
    sdstolower(s);
    assert_true(0 == strcmp(s, "hello"));
    sdstoupper(s);
    assert_true(0 == strcmp(s, "HELLO"));
    sdsfree(s);
}

void test_sdsfromlonglong(void **state)
{
    sds s = sdsfromlonglong(100);
    assert_true(0 == strcmp(s, "100"));
    assert_int_equal(3, sdslen(s));
    sdsfree(s);
}

void test_join(void **state)
{
    char *argv[] = {"abc", "def", "ghi"};

    sds s = sdsjoin(argv, 3, " ");
    assert_true(strcmp(s, "abc def ghi") == 0);
}

int main(int argc, char *argv[])
{
    const UnitTest tests[] = {
            unit_test(test_newlen),
            unit_test(test_empty),
            unit_test(test_new),
            unit_test(test_dup),
            unit_test(test_growzero),
            unit_test(test_catlen),
            unit_test(test_cat),
            unit_test(test_catsds),
            unit_test(test_cpylen),
            unit_test(test_trim),
            unit_test(test_range),
            unit_test(test_cmp),
            unit_test(test_splitlen),
            unit_test(test_slowerupper),
            unit_test(test_sdsfromlonglong),
            unit_test(test_join)
    };
    return run_tests(tests);
}